package model.parseTree;

import model.searchers.ISearcher;
import model.searchers.URLList;

/**
 * Class OrNode represents a special type of node in a syntax tree. It is used
 * to represent the boolean operator disjunction. It keeps track of its children.
 * The result of evaluating an object of class OrNode is the union of results obtained by 
 * evaluating the left and right subtrees.
 * 
 */
public class OrNode extends SearchNode {
	
	
	/**
	 * Constructor of OrNode. Creates a search node with value "OR" and the specified child nodes.
	 * 
	 * @param leftChild		left child node
	 * @param rightChild	right child node
	 */
	public OrNode(SearchNode leftChild, SearchNode rightChild) {
		super(leftChild, rightChild, "OR");
	}

	/**
	 * Returns the resulting list of URLs containing both the URLs that are
	 * results of search on right subquery (subtree) and left subquery (subtree)
	 * 
	 * @param searcher	the searcher to perform the search for the URLs
	 * @return list of results of OR-search
	 */
	@Override
	public URLList getResult(ISearcher searcher) {
		// find results of left and right subtrees
		URLList startLeftResult = (getLeft() == null) ? null : getLeft()
				.getResult(searcher);
		URLList currentLeft = startLeftResult;
		URLList startRightResult = (getRight() == null) ? null : getRight()
				.getResult(searcher);
		URLList currentRight = startRightResult;
		URLList result;
		boolean found = false;

		if (startRightResult != null) {
			result = startRightResult.clone();

			// get all combinations of URLList objects in each of the results
			while (currentLeft != null) {
				while (currentRight != null) {
			
					// if two result elements agree on an url, the total number of occurrences increased
					if (currentLeft.getValue().equals(currentRight.getValue())) {
						found = true;
						URLList match = (URLList) result.getFromList(currentLeft.getValue());
						match.setOccurrences(currentLeft.getOccurrences()
								+ currentRight.getOccurrences());
	
					// if the url currentRight is not already among the results, it is added
					} else if (currentRight.getNext() == null && found == false) {
						URLList newResultElement = new URLList(
								currentLeft.getValue(),
								currentLeft.getOccurrences(), result);
						result = newResultElement;
					}
					currentRight = (URLList) currentRight.getNext();
				}
				found = false;
				currentLeft = (URLList) currentLeft.getNext();
				currentRight = startRightResult;
			}
		} else {
			result = startLeftResult;
		}
		return result;
	}
}
